package utils

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"time"
	"xinduobang/stock/core"
)

// 如果需要自己锁自己解锁，需要传入value，如果不需要，传入空字符串
func Lock(c *gin.Context, lockKey string, value string) (isSuccess bool, err error) {
	const RedisLockDefaultTime = 20 * time.Second

	rd, err := core.GetRedis()
	if err != nil {
		Errorf(c, "get redis error:%s", err.Error())
		return
	}

	ret := rd.SetNX(c, lockKey, value, RedisLockDefaultTime)
	if ret.Err() != nil {
		Errorf(c, "setnx error:%s", ret.Err().Error())
		return
	}

	isSuccess = ret.Val()
	if isSuccess == false {
		Errorf(c, "lock has been Locked lockKey:%v", lockKey)
		return isSuccess, errors.New("lock has been Locked")
	}

	return
}

func UnLock(c *gin.Context, lockKey string, value string) (err error) {
	rd, err := core.GetRedis()
	if err != nil {
		Errorf(c, "get redis error:%s", err.Error())
		return
	}
	if value == "" {
		ret := rd.Del(c, lockKey)
		if ret.Err() != nil {
			Errorf(c, "del error:%s", ret.Err().Error())
		}
		return
	}

	// 判断是否存在直接用err是不是为空
	res := rd.Get(c, lockKey)
	if res.Err() != nil {
		if res.Err() == redis.Nil {
			err = errors.New("key not exists")
			Error(c, err, lockKey, res.Err().Error())
			return
		} else {
			Errorf(c, "get error:%s", res.Err().Error())
			return
		}
	}

	if res.Val() != value {
		err = errors.New("value not equal")
		Error(c, err)
		return
	}

	ret := rd.Del(c, lockKey)
	if ret.Err() != nil {
		Errorf(c, "del error:%s", ret.Err().Error())
		return
	}

	return
}
